﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using JetBrains.Annotations;
using Orchard;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Contrib.DecoratorField.Settings;
using Contrib.DecoratorField.ViewModels;
using Orchard.ContentManagement.Handlers;
using Orchard.Localization;

namespace Contrib.DecoratorField.Drivers {
    [UsedImplicitly]
    public class DecoratorFieldDriver : ContentFieldDriver<Fields.DecoratorField> {
        public IOrchardServices Services { get; set; }

        // EditorTemplates/Fields/Custom.DateTime.cshtml
        private const string TemplateName       =   "Fields/Contrib.Decorator";
        private const string TokenContentType   =   "{content-type}";
        private const string TokenFieldName     =   "{field-name}";
        private const string TokenContentItemId =   "{content-item-id}";

        public DecoratorFieldDriver(IOrchardServices services) {
            Services = services;
            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        private static string GetPrefix(ContentField field, ContentPart part) {
            // handles spaces in field names
            return (part.PartDefinition.Name + "." + field.Name)
                   .Replace(" ", "_");
        }

        protected override DriverResult Display(
            ContentPart part, Fields.DecoratorField field,
            string displayType, dynamic shapeHelper) {

            var settings = field.PartFieldDefinition.Settings.GetModel<DecoratorFieldSettings>();
            var viewModel = new DecoratorFieldViewModel
            {
                Name = field.Name,
                Settings = settings
            };

            return ContentShape("Fields_Contrib_Decorator", // key in Shape Table
                    field.Name, // used to differentiate shapes in placement.info overrides, e.g. Fields_Common_Text-DIFFERENTIATOR
                    // this is the actual Shape which will be resolved
                    // (Fields/Contrib.Decorator.cshtml)
                    () => shapeHelper.Fields_Contrib_Decorator(Model: viewModel, ContentPart: part, // it will allow to access the content item
                        ContentField: field)
                );
        }

        protected override DriverResult Editor(ContentPart part,
                                               Fields.DecoratorField field,
                                               dynamic shapeHelper) {

            DecoratorFieldSettings settings = field.PartFieldDefinition.Settings.GetModel<DecoratorFieldSettings>();
            var viewModel = new DecoratorFieldViewModel
            {
                Name        =   field.Name,
                Field       = field,
                Settings     =   settings
            };

            return ContentShape("Fields_Contrib_Decorator_Edit",field.Name,
                () => shapeHelper.EditorTemplate(
                          TemplateName: TemplateName,
                          Model: viewModel,
                          Prefix: GetPrefix(field, part)));
        }

        protected override DriverResult Editor(ContentPart part,
                                               Fields.DecoratorField field,
                                               IUpdateModel updater,
                                               dynamic shapeHelper) {

            var settings = field.PartFieldDefinition.Settings.GetModel<DecoratorFieldSettings>();
            var viewModel = new DecoratorFieldViewModel
            {
                Settings = settings,
                Field = field,
                Name = field.Name
            };
            updater.TryUpdateModel(viewModel,GetPrefix(field, part), null, null);

            return Editor(part, field, shapeHelper);
        }

        private static string FormatWithTokens(string value, string contentType, string fieldName, int contentItemId)
        {
            if (String.IsNullOrWhiteSpace(value))
            {
                return String.Empty;
            }

            return value
                .Replace(TokenContentType, contentType)
                .Replace(TokenFieldName, fieldName)
                .Replace(TokenContentItemId, Convert.ToString(contentItemId));

        }

        protected override void Importing(ContentPart part, Fields.DecoratorField field, 
            ImportContentContext context) {

        }

        protected override void Exporting(ContentPart part, Fields.DecoratorField field, 
            ExportContentContext context) {
        }
    }
}